package org.kjtc.controller;

import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.kjtc.emoji.EmojiParser;
import org.kjtc.entity.WechatUser;
import org.kjtc.service.WeChartService;
import org.kjtc.weChatUtil.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * token验证（服务器端）
 */
@WebServlet("/WeChatCheck")
public class WeChatCheck extends HttpServlet {

	private static Logger logger = Logger.getLogger(WeChatCheck.class);
	private static final long serialVersionUID = 1L;

	@Autowired
	private WeChartService weChartService;

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

    public WeChatCheck() {
		super();
	}

	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
	}

    private boolean checkSignature(HttpServletRequest request) {
    	String signature = request.getParameter("signature");
		String nonce = request.getParameter("nonce");
		String timestamp = request.getParameter("timestamp");
		String token = "ThisTokenMadeMeLaughAndScribble";//随意填写要和微信官网上的一致

    	String [] arr = {token, timestamp, nonce};
    	Arrays.sort(arr);
    	String my_signature = DigestUtils.sha1Hex(StringUtils.join(arr));
    	return my_signature.equals(signature);
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		logger.info("微信服务器接收到Get请求：" + request.getRequestURI());
		if(!checkSignature(request)){
			return;
		}
		String echostr = request.getParameter("echostr");
		OutputStream out = response.getOutputStream();
		out.write(echostr.getBytes());
		out.flush();
		out.close();
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	InputStream is = request.getInputStream();
		InputStreamReader isr = new InputStreamReader(is);
		BufferedReader br = new BufferedReader(isr);
		StringBuffer sb = new StringBuffer();
		String tempStr = "";
		while ((tempStr = br.readLine()) != null) {
			sb.append(tempStr);
		}
		String xmlStr = sb.toString();
		isr = null;
		br = null;
		sb = null;
		String xml = new String(xmlStr.getBytes("gbk"), "UTF-8");
		String toUserName = "";
		String fromUserName = "";
		String createTime = "";
		String msgType = "";
		String event = "";
		try {
			Document doc = DocumentHelper.parseText(xml);
			Element root = doc.getRootElement();
			// 开发者微信号
			toUserName = root.elementTextTrim("ToUserName");
			// 发送方帐号（一个OpenID）
			fromUserName = root.elementTextTrim("FromUserName");
			// 消息创建时间 （整型）
			createTime = root.elementTextTrim("CreateTime");
			// 消息类型，event
			msgType = root.elementTextTrim("MsgType");
			// 事件类型，subscribe(订阅)、unsubscribe(取消订阅)
			event = root.elementTextTrim("Event");
		} catch (Exception e) {
			logger.error("Post请求XML数据：" + xmlStr + "，解析异常：" + e.getMessage());
		}
		logger.info("微信服务器接收到Post请求【" + event + "】数据：" + xmlStr);
		try {
			WechatUser wechatUser = new WechatUser();
			wechatUser.setWeChatID(fromUserName);
			Date date = new Date();
			// 公众号关注
			if ("subscribe".equals(event)) {
				String token = CommonUtil.getToken(CommonUtil.appid, CommonUtil.appsecret, redisTemplate);
				if (StringUtils.isEmpty(token)) {
					logger.error("关注用户(" + fromUserName + ")信息获取失败：获取微信(token)失败");
				} else {
					JSONObject userJson = CommonUtil.getWechatUserInfo(token, fromUserName, null);
					if (userJson != null && userJson.has("subscribe") && "1".equals(userJson.getString("subscribe"))) {
						if (userJson.has("nickname")) {
							fromUserName = userJson.getString("nickname");
							if (userJson.has("remark") && !StringUtils.isEmpty(userJson.getString("remark"))) {
								fromUserName += "(" + userJson.getString("remark") + ")";
							}
							wechatUser.setWeChatNickName(EmojiParser.replaceAllEmojis(fromUserName, "*"));
						}
						if (userJson.has("headimgurl")) {
							wechatUser.setWeChatImageUrl(userJson.getString("headimgurl"));
						}
						if (userJson.has("subscribe_time")) {
							date.setTime(Long.parseLong(userJson.getString("subscribe_time")) * 1000);
						}
					} else {
						date.setTime(Long.parseLong(createTime) * 1000);
						logger.warn("关注用户(" + fromUserName + ")信息获取失败：用户取消关注");
					}

					List<WechatUser> userList = weChartService.searchWechatUser(wechatUser);
					if (userList != null && userList.size() > 0) {
						wechatUser = userList.get(0);
						if (!wechatUser.isEnabled()) {
							wechatUser.setUpdateUser("subscribe");
							wechatUser.setSubscribeTime(date);
							wechatUser.setEnabled(true);
							weChartService.syncWechatUser(wechatUser);
							fromUserName = fromUserName + "(再次关注)";
						}
					} else {
						wechatUser.setSubscribeTime(date);
						wechatUser.setCreateUser("subscribe");
						wechatUser.setUpdateUser("subscribe");
						weChartService.saveWechatUser(wechatUser);
						fromUserName = fromUserName + "(新关注)";
					}
					logger.info(CommonUtil.date2Str(date, null) + "新用户：" + fromUserName + "关注公众号");

					// 发送用户关注信息
					List<String> keywordList = new ArrayList<String>();
					keywordList.add(fromUserName);
					keywordList.add(CommonUtil.date2Str(date, null));
					CommonUtil.sendWechatMessage("subscribe", keywordList, weChartService, redisTemplate);
					keywordList = null;
				}
			}
			// 取消关注
			if ("unsubscribe".equals(event)) {
				String userName = fromUserName;
				List<WechatUser> userList = weChartService.searchWechatUser(wechatUser);
				if (userList != null && userList.size() > 0) {
					wechatUser = userList.get(0);
					fromUserName = wechatUser.getWeChatNickName();
					wechatUser.setUpdateUser("unsubscribe");
					wechatUser.setUnsubscribeTime(date);
					wechatUser.setEnabled(false);
					weChartService.syncWechatUser(wechatUser);
				}
				logger.info(CommonUtil.date2Str(date, null) + "用户：" + fromUserName + "取消关注公众号");

				// 发送用户取消关注信息
				List<String> keywordList = new ArrayList<String>();
				if (StringUtils.isEmpty(wechatUser.getUserName())) {
					if (StringUtils.isEmpty(wechatUser.getUserID())) {
						if (StringUtils.isEmpty(wechatUser.getMobile())) {
							userName = "取关用户：" + userName;
						} else {
							userName = wechatUser.getMobile();
						}
					} else {
						userName = wechatUser.getUserID();
					}
				} else {
					userName = wechatUser.getUserName();
				}
				keywordList.add(fromUserName);
				keywordList.add(fromUserName);
				keywordList.add(CommonUtil.date2Str(date, null));
				CommonUtil.sendWechatMessage("unsubscribe", keywordList, weChartService, redisTemplate);
				keywordList = null;
			}
			wechatUser = null;

			OutputStream out = response.getOutputStream();
			out.write("".getBytes());
			out.flush();
			out.close();
		} catch (Exception e) {
			logger.error("微信服务器接收到Post请求【" + event + "】数据处理异常：" + e.getMessage());
		}

	}
}